#include "cardlist.h"

CardList::CardList( DbLink* pcDbLink, wxString& soundFileDir )
: CardDialog( NULL ), BaseList( m_listCtrl, soundFileDir )
{	
	m_pcDbLink = pcDbLink;
	m_pDictDb  = pcDbLink->GetDictDb();
	m_pCardDb  = pcDbLink->GetCardDb();

	m_iCardNum = -1;
	
	m_listCtrl->InsertColumn( eCard_Name,       _("Card name"),            wxLIST_FORMAT_LEFT, 120 );
	m_listCtrl->InsertColumn( eCard_PrimLang,   _("Primary language"),     wxLIST_FORMAT_LEFT, 135 );
	m_listCtrl->InsertColumn( eCard_TranLang,   _("Translation language"), wxLIST_FORMAT_LEFT, 160 );	
	m_listCtrl->InsertColumn( eCard_TableName,  _("Table name"),           wxLIST_FORMAT_LEFT, 0 );
	m_listCtrl->InsertColumn( eCard_TotalWords, _("Total words"),          wxLIST_FORMAT_LEFT, 95 );
	m_listCtrl->InsertColumn( eCard_WordsLeft,  _("Words Left"),           wxLIST_FORMAT_LEFT, 90 );
	m_listCtrl->InsertColumn( eCard_Learn,      _("Learn"),                wxLIST_FORMAT_LEFT, 50 );
	
	m_buttonOk->SetFocus();
}

CardList::~CardList()
{
}

void CardList::OnEnterWindow( wxMouseEvent& event )
{
	m_listCtrl->SetFocus();
}

void CardList::OnOkClick( wxCommandEvent& event )
{
	wxString sPrimLang = GetPrimLang();
	wxString sTranLang = GetTranLang();
	wxString sCardName = GetCardName();
	wxString sLearn    = GetLearn();
		
	if( ( sPrimLang.empty() && sTranLang.empty() && sCardName.empty() && m_sLearn.empty() ) || ( sPrimLang == m_sPrimLang && sTranLang == m_sTranLang && sCardName == m_sCardName ) )
	{
		if( IsModal() )
		{
			// update learn flag in db
			if( sLearn != m_sLearn )
				m_pCardDb->ExecuteUpdate( wxT( "UPDATE cards SET learn = ") + StrToBool( sLearn ) + wxT(" WHERE cardtable = '") + m_sTableName + wxT("'") );

			EndModal( wxID_OK );
		}
		return;
	}
	
	// create db
	if( m_sPrimLang.empty() && m_sTranLang.empty() && m_sCardName.empty() )
	{
		OnCreateClick( event );
		return;		
	}
	
	sLearn = StrToBool( sLearn );
		
	// update db entry
	if( ( sPrimLang != m_sPrimLang && !sPrimLang.empty() && !m_sPrimLang.empty() ) || 
	    ( sTranLang != m_sTranLang && !sTranLang.empty() && !m_sTranLang.empty() ) || 
			( sCardName != m_sCardName && !sCardName.empty() && !m_sCardName.empty() ) ||
			( sLearn != m_sLearn && !sLearn.empty() && !m_sLearn.empty()) )
	{	
		wxString sQuery = wxT( "UPDATE cards SET cardname = '") + sCardName + wxT("', primlang = '") + sPrimLang + 
		wxT("', tranlang = '") + sTranLang + wxT("', learn = ") + sLearn + wxT(" WHERE cardtable = '") + m_sTableName + wxT("'");

		m_pCardDb->ExecuteUpdate( sQuery );
		
		// uodate item text in the list
		UpdateItem();
	}
	else
		wxMessageDialog( NULL, wxT("Nothing to update"), wxT("Info"), wxOK | wxICON_INFORMATION ).ShowModal();
}
	
void CardList::OnCancelClick( wxCommandEvent& WXUNUSED( event ) )
{
	if( IsModal() )
		EndModal( wxID_CANCEL );
}

void CardList::OnOpenClick( wxCommandEvent& WXUNUSED( event ) )
{
	if( m_lItemIdx < 0 || m_sTableName == _("") )
		return;
		
	CardWordList cWord( m_pcDbLink, m_sTableName, m_sSoundDir );
	cWord.Load();
	cWord.ShowModal();
	
	// reload the list
	m_iCardNum = FillCardList( true );
}

void CardList::ClearText()
{
	wxString s = _("");
	SetCardName( s );
	SetPrimLang( s );
	SetTranLang( s );
	SetLearn( false );
}

void CardList::OnDeleteClick( wxCommandEvent& WXUNUSED( event ) )
{
	if( m_lItemIdx < 0 || m_sTableName.empty() )
		return;	
	
	// get last card table from db
	wxSQLite3ResultSet cResultSet = m_pCardDb->ExecuteQuery( wxT( "SELECT cardtable FROM cards ORDER BY cardtable DESC LIMIT 1" ) );
	wxString sLastTableName = cResultSet.GetAsString(0);
	cResultSet.Finalize();

	m_pcDbLink->FinalizeSets();

	// delete card db entry
	m_pCardDb->ExecuteUpdate( wxT( "DROP TABLE " ) + m_sTableName );
	
	// delete table from db
	m_pCardDb->ExecuteUpdate( wxT( "DELETE FROM cards WHERE cardtable = '" ) + m_sTableName + wxT("'") );
		
	m_iCardNum--;

	if( sLastTableName != m_sTableName )
	{
		// update table names
		m_pCardDb->ExecuteUpdate( wxT("ALTER TABLE ") + sLastTableName + wxT(" RENAME TO ") + m_sTableName );
		m_pCardDb->ExecuteUpdate( wxT("UPDATE cards SET cardtable = '") + m_sTableName + wxT("' WHERE cardtable = '") + sLastTableName + wxT("'") );
		
		// update list		
		m_pcListCtrl->SetItem( m_iCardNum, eCard_TableName, m_sTableName );
	}
	
	// delete item from the list
	m_pcListCtrl->DeleteItem( m_lItemIdx );
}

void CardList::OnCardSelected( wxListEvent& WXUNUSED( event ) )
{	
	m_lItemIdx = -1;
	m_lItemIdx = m_listCtrl->GetNextItem( m_lItemIdx, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED );

	m_sTableName = _("");
		
	if( m_lItemIdx >= 0 )
	{			
		m_sTableName = GetColumnText( eCard_TableName );
		m_sCardName = GetColumnText( eCard_Name );
		m_sPrimLang = GetColumnText( eCard_PrimLang );
		m_sTranLang = GetColumnText( eCard_TranLang );
		m_sLearn    = GetColumnText( eCard_Learn );

		wxString wordsLeft = GetColumnText( eCard_WordsLeft );
		
		SetCardName( m_sCardName );
		SetPrimLang( m_sPrimLang );
		SetTranLang( m_sTranLang );
		SetLearn( m_sLearn );
		
		m_buttonDelete->Enable( true );
		m_buttonOpen->Enable( true );
		
		if( wordsLeft != wxT("0") )
			m_checkBoxLearn->Enable( true );
	}
}

void CardList::OnCardDeselected( wxListEvent& WXUNUSED( event ) )
{	
	ClearText();
	ClearInfo();
}

long CardList::FillCardList( bool bClear )
{
	// clear list
	if( bClear )
	{
		ClearText();
		ClearInfo();
		m_pcListCtrl->DeleteAllItems();
	}
		
	// get list of tables in the db
	wxSQLite3ResultSet cCardSet = m_pCardDb->ExecuteQuery( wxT( "SELECT * FROM cards" ) );
	long iCount = 0;
	
	// fill the card list
	while( cCardSet.NextRow() )
	{			
		// get card info
		wxString sTableName = cCardSet.GetAsString(0);
		wxString sCardName = cCardSet.GetAsString(1);
		wxString sPrimLang = cCardSet.GetAsString(2);
		wxString sTranLang = cCardSet.GetAsString(3);
		wxString sLearn = cCardSet.GetAsString(4);
		sLearn = BoolToStr( sLearn );
		
		// get number of words in the card
		wxString sQuery = wxT( "SELECT count(*) FROM " )  + sTableName;
		wxSQLite3ResultSet cResultSet = m_pCardDb->ExecuteQuery( sQuery );
		wxString sWords = cResultSet.GetAsString(0);
		cResultSet.Finalize();
		
		sQuery = wxT( "SELECT count(*) FROM " )  + sTableName + wxT(" WHERE score < 100");
		cResultSet = m_pCardDb->ExecuteQuery( sQuery );
		wxString sWordsLeft = cResultSet.GetAsString(0);
		cResultSet.Finalize();
		
		wxString s[eCard_Cols];
		
		s[eCard_TableName] = sTableName;
		s[eCard_Name] = sCardName;
		s[eCard_PrimLang] = sPrimLang;
		s[eCard_TranLang] = sTranLang;
		s[eCard_TotalWords] = sWords;
		s[eCard_WordsLeft] = sWordsLeft;
		s[eCard_Learn] = sLearn;
		
		InsertItem( s, eCard_Cols );
		
		iCount++;
	}
	cCardSet.Finalize();
	
	return iCount;
}

void CardList::OnCreateClick( wxCommandEvent& WXUNUSED( event ) )
{
	// try do add new db entry
	if( GetCardName().empty() )
	{
		m_textCtrl->SetFocus();
	}
	else if( GetPrimLang().empty() )
	{
		m_textCtrlPrimLang->SetFocus();
	}
	else if( GetTranLang().empty() )
	{
		m_textCtrlTranLang->SetFocus();
	}
	else
	{
		m_sTableName = wxT( "card" );
		m_sTableName << m_iCardNum;
			
		wxString sQuery = wxT( "CREATE TABLE " ) + m_sTableName + wxT( "( id INTEGER, dicttable VARCHAR(8), score INTEGER )" );			
		m_pCardDb->ExecuteUpdate( sQuery );
		
		sQuery = wxT( "INSERT INTO cards VALUES ('") + m_sTableName + wxT("', '") + GetCardName() + wxT("', '") + GetPrimLang() + wxT("', '") + GetTranLang() + wxT("', 0)");				
		m_pCardDb->ExecuteUpdate( sQuery );
		
		wxString s[eCard_Cols];
		s[eCard_TableName]  = m_sTableName;
		s[eCard_Name]       = GetCardName();
		s[eCard_PrimLang]   = GetPrimLang();
		s[eCard_TranLang]   = GetTranLang();
		s[eCard_TotalWords] = wxT("0");
		s[eCard_WordsLeft]  = wxT("0");
		s[eCard_Learn]      = wxT("no");

		InsertItem( s, eCard_Cols );
		
		ClearText();
		
		m_iCardNum++;
	}	
}

void CardList::Load()
{
	m_iCardNum = FillCardList();
}

void CardList::UpdateItem()
{
	if( m_lItemIdx < 0 )
		return;
		
	m_sPrimLang = GetPrimLang();
	m_sTranLang = GetTranLang();
	m_sCardName = GetCardName();	
	m_sLearn = GetLearn();
	
	m_listCtrl->SetItem( m_lItemIdx, eCard_Name, m_sCardName );
	m_listCtrl->SetItem( m_lItemIdx, eCard_PrimLang, m_sPrimLang );
	m_listCtrl->SetItem( m_lItemIdx, eCard_TranLang, m_sTranLang );
	m_listCtrl->SetItem( m_lItemIdx, eCard_Learn, m_sLearn );
}

void CardList::TablesUpdate( long iNum )
{
	// get list of tables in the db
	wxSQLite3ResultSet cCardSet = m_pCardDb->ExecuteQuery( wxT( "SELECT cardtable FROM cards" ) );

	long iCount = 0;
	
	while( cCardSet.NextRow() )
	{			
		wxString sTableName = cCardSet.GetAsString(0);
		long idx = TableToLong( sTableName );
		
		if( idx > iNum )
		{
			wxString sNewTable = wxT("card");
			sNewTable << ( idx - 1 );
			// update table name
			m_pCardDb->ExecuteUpdate( wxT("UPDATE cards SET cardtable = '") + sNewTable + wxT("' WHERE cardtable = '") + sTableName + wxT("'") );
			
			// change table name
			m_pCardDb->ExecuteUpdate( wxT("ALTER TABLE ") + sTableName + wxT(" RENAME TO ") + sNewTable );
			
			// update text in the list
			m_listCtrl->SetItem( iCount, eCard_TableName, sNewTable );
		}		
		
		iCount++;
	}
	cCardSet.Finalize();
}

void CardList::ClearInfo()
{
	m_sPrimLang.clear();
	m_sTranLang.clear();
	m_sCardName.clear();
	m_sTableName.clear();
	m_sLearn.clear();
	
	m_buttonDelete->Enable( false );
	m_buttonOpen->Enable( false );
	m_checkBoxLearn->Enable( false );
}

void CardList::OnKeyDown( wxKeyEvent& event )
{
	if( event.GetKeyCode() == WXK_ESCAPE )
		OnCancelClick( (wxCommandEvent&) event );
	else
		event.Skip();
}

void CardList::OnLearnClick( wxMouseEvent& event )
{
	if( m_lItemIdx >= 0 )
	{
		wxString temp = GetLearn( 1 - m_checkBoxLearn->GetValue() );
		m_pcListCtrl->SetItem( m_lItemIdx, eCard_Learn,  temp );
	}

	event.Skip();
}